libkovan  1
The kovan standard library
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
create.hpp
Go to the documentation of this file.
1 /**************************************************************************
2  * Copyright 2012 KISS Institute for Practical Robotics *
3  * *
4  * This file is part of libkovan. *
5  * *
6  * libkovan is free software: you can redistribute it and/or modify *
7  * it under the terms of the GNU General Public License as published by *
8  * the Free Software Foundation, either version 2 of the License, or *
9  * (at your option) any later version. *
10  * *
11  * libkovan is distributed in the hope that it will be useful, *
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of *
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
14  * GNU General Public License for more details. *
15  * *
16  * You should have received a copy of the GNU General Public License *
17  * along with libkovan. Check the LICENSE file in the project root. *
18  * If not, see <http://www.gnu.org/licenses/>. *
19  **************************************************************************/
20 
34 #ifndef _CREATE_HPP_
35 #define _CREATE_HPP_
36 
37 #include <cstdio>
38 #include <cstdlib>
39 #include <vector>
40 
41 #ifndef WIN32
42 #include <sys/time.h>
43 #include <termios.h>
44 #include <pthread.h>
45 #else
46 #include <time.h>
47 #include <winsock2.h>
48 typedef unsigned int speed_t;
49 #endif
50 
51 #include "sensor.hpp"
52 #include "button.hpp"
53 #include "export.h"
54 
55 #define PI 3.14159f
56 
62 {
63 public:
64  CreateScript();
65  CreateScript(const CreateScript& rhs);
66 
67  void append(const unsigned char& byte);
68  void append(const unsigned char *data, const size_t& size);
69  void append(const CreateScript& script);
70 
71  void remove(const size_t& i, const size_t& len = 1);
72 
73  const unsigned char *data() const;
74  size_t size() const;
75 
76  unsigned char byte(const size_t& i);
77 
78  CreateScript& operator=(const CreateScript& rhs);
79 
80 private:
81  std::vector<unsigned char> m_script;
82 };
83 
88 {
89  timeval timestamp;
90 
91  int distance;
92  int angle;
93  short radius;
95  short leftVelocity;
96 };
97 
101 namespace CreatePackets
102 {
106  struct _1
107  {
108  unsigned char bumpsAndWheelDrops;
109  unsigned char wall;
110  unsigned char cliffLeft;
111  unsigned char cliffFrontLeft;
112  unsigned char cliffFrontRight;
113  unsigned char cliffRight;
114  unsigned char virtualWall;
115  unsigned char cargoBayDigitalInputs;
117  };
118 
122  struct _2
123  {
124  unsigned char ir;
125  unsigned char buttons;
126  unsigned char distance[2];
127  unsigned char angle[2];
128  };
129 
133  struct _3
134  {
135  unsigned char chargingState;
136  unsigned char voltage[2];
137  char current[2];
139  unsigned char batteryCharge[2];
140  unsigned char batteryCapacity[2];
141  };
142 
146  struct _4
147  {
148  unsigned char wallSignal[2];
149  unsigned char cliffLeftSignal[2];
150  unsigned char cliffFrontLeftSignal[2];
151  unsigned char cliffFrontRightSignal[2];
152  unsigned char cliffRightSignal[2];
153  unsigned char userDigitalInputs;
154  unsigned char userAnalogInput[2];
156  };
157 
161  struct _5
162  {
163  unsigned char mode;
164  unsigned char songNumber;
165  unsigned char songPlaying;
166  unsigned char numberOfStreamPackets;
167  char velocity[2];
168  char radius[2];
169  char rightVelocity[2];
170  char leftVelocity[2];
171  };
172 }
173 
174 namespace CreateSensors
175 {
176  class PlayButton;
177  class AdvanceButton;
178  class Wall;
179  class CliffLeft;
180  class CliffFrontLeft;
181  class CliffFrontRight;
182  class CliffRight;
183  class VirtualWall;
184  class WallSignal;
185  class CliffLeftSignal;
186  class CliffFrontLeftSignal;
187  class CliffFrontRightSignal;
188  class CliffRightSignal;
189  class CargoBayAnalogSignal;
190  class CargoBayDigitalInputs;
191  class IR;
192  class ChargingState;
193  class BatteryTemperature;
194  class BatteryCharge;
195  class BatteryCapacity;
196  class Angle;
197  class Distance;
198  class BumpLeft;
199  class BumpRight;
200  class WheelDropRight;
201  class WheelDropLeft;
202  class WheelDropCaster;
203 }
204 
213 {
214 public:
221  enum Mode {
225  FullMode
226  };
227 
228  ~Create();
229 
236  bool connect();
237 
244  bool disconnect();
245 
251  bool isConnected() const;
252 
253  void setPassiveMode();
254  void setSafeMode();
255  void setFullMode();
256 
257  void setMode(const Create::Mode& mode);
258  Create::Mode mode();
259 
260  void send(const CreateScript& script);
261 
262  bool write(const unsigned char& c);
263  bool write(const unsigned char *data, const size_t& len);
264 
265  void flush();
266 
271  short read();
272 
279  int read(unsigned char *data, const size_t& len);
280 
288  bool blockingRead(unsigned char *data, const size_t& size, unsigned timeout = 25);
289 
290 
291  template<typename T>
292  inline bool blockingRead(T& data, unsigned timeout = 0)
293  {
294  return blockingRead(reinterpret_cast<unsigned char *>(&data), sizeof(T),
295  timeout ? timeout : sizeof(T) * 7);
296  }
297 
298  void setLeds(const bool& advance, const bool& play, const unsigned char& color, const unsigned char& brightness);
299 
300  void drive(const short& velocity, const short& radius);
301  void driveDirect(const short& left, const short& right);
302  inline void driveStraight(const short& speed) { driveDirect(speed, speed); }
303  inline void stop()
304  {
305  flush();
306  driveStraight(0);
307  }
308 
315  void turn(const short& angle, const unsigned short& speed);
316 
323  void move(const short& millimeters, const unsigned short& speed);
324 
329  void spin(const short& speed);
330 
336  short angularVelocity() const;
337 
338  inline void spinClockwise(const short& speed) { spin(-speed); }
339  inline void spinCounterClockwise(const short& speed) { spin(speed); }
340 
341  bool setBaudRate(const unsigned char& baudCode);
342 
343  void setDistance(const int distance);
344  void setAngle(const int angle);
345 
346  // High level sensors
347  AbstractButton *playButton() const;
348  AbstractButton *advanceButton() const;
349 
350  Sensor<bool> *wall() const;
351  Sensor<bool> *cliffLeft() const;
352  Sensor<bool> *cliffFrontLeft() const;
353  Sensor<bool> *cliffFrontRight() const;
354  Sensor<bool> *cliffRight() const;
355  Sensor<bool> *virtualWall() const;
356 
357  Sensor<unsigned short> *wallSignal() const;
358  Sensor<unsigned short> *cliffLeftSignal() const;
359  Sensor<unsigned short> *cliffFrontLeftSignal() const;
360  Sensor<unsigned short> *cliffFrontRightSignal() const;
361  Sensor<unsigned short> *cliffRightSignal() const;
362  Sensor<unsigned short> *cargoBayAnalogSignal() const;
363  Sensor<unsigned char> *cargoBayDigitalInputs() const;
364 
365  Sensor<unsigned char> *ir() const;
366 
367  Sensor<unsigned char> *chargingState() const;
368  Sensor<char> *batteryTemperature() const;
369  Sensor<unsigned short> *batteryCharge() const;
370  Sensor<unsigned short> *batteryCapacity() const;
371 
372  Sensor<int> *angle() const;
373  Sensor<int> *distance() const;
374 
375  Sensor<bool> *bumpLeft() const;
376  Sensor<bool> *bumpRight() const;
377 
378  Sensor<bool> *wheelDropLeft() const;
379  Sensor<bool> *wheelDropRight() const;
380  Sensor<bool> *wheelDropCaster() const;
381 
382  void setRefreshRate(const unsigned short& refreshRate);
383  const unsigned short& refreshRate() const;
384 
390  static Create *instance();
391 
392  const CreateState *state();
393  const CreatePackets::_1 *sensorPacket1();
394  const CreatePackets::_2 *sensorPacket2();
395  const CreatePackets::_3 *sensorPacket3();
396  const CreatePackets::_4 *sensorPacket4();
397  const CreatePackets::_5 *sensorPacket5();
398 
399  inline void beginAtomicOperation()
400  {
401  #ifndef WIN32
402  pthread_mutex_lock(&m_mutex);
403  #endif
404  }
405 
406  inline void endAtomicOperation()
407  {
408  #ifndef WIN32
409  pthread_mutex_unlock(&m_mutex);
410  #endif
411  }
412 
413 private:
414  Create();
415  Create(const Create& rhs);
416  Create& operator=(const Create& rhs);
417 
418  void setLocalBaudRate(const speed_t& baudRate);
419 
420  bool start();
421 
422  bool open();
423  void close();
424 
425  template<typename T>
426  inline void lazyDelete(T *&ptr)
427  {
428  if(ptr) delete ptr;
429  }
430 
431  inline timeval timeOfDay() const
432  {
433 #ifdef _MSC_VER
434  FILETIME ft;
435  GetSystemTimeAsFileTime(&ft);
436  unsigned long t = (ULONGLONG)ft.dwLowDateTime + ((ULONGLONG)(ft.dwHighDateTime) << 32);
437 
438  timeval tv;
439  tv.tv_usec = t % 1000L;
440  tv.tv_sec = (t - tv.tv_usec) / 1000L;
441  return tv;
442 #else
443  timeval ret;
444  gettimeofday(&ret, NULL);
445  return ret;
446 #endif
447  }
448 
449  inline bool hasRequiredTimePassed(const timeval& timestamp) const
450  {
451  #ifndef WIN32
452  timeval current = timeOfDay();
453  timeval result;
454  timersub(&current, &timestamp, &result);
455  const long msecs = result.tv_sec * 1000 + result.tv_usec / 1000;
456  return msecs > m_refreshRate;
457  #else
458  #pragma message ("Create library not yet implemented for Windows")
459  return false;
460  #endif
461  }
462 
463  inline double timevalToFloat(const timeval& tv)
464  {
465  return ((double)tv.tv_sec) + ((double)tv.tv_usec / 1000000.0);
466  }
467 
468  inline float deg2rad(const float& deg)
469  {
470  return deg / 180.0 * PI;
471  }
472 
473  void updateState();
474 
475  void updateSensorPacket1();
476  void updateSensorPacket2(bool forceUpdate = false);
477  void updateSensorPacket3();
478  void updateSensorPacket4();
479  void updateSensorPacket5();
480 
481  CreateState m_state;
482 
483  unsigned short m_refreshRate;
484 
485  CreatePackets::_1 m_1;
486  CreatePackets::_2 m_2;
487  CreatePackets::_3 m_3;
488  CreatePackets::_4 m_4;
489  CreatePackets::_5 m_5;
490  timeval timestamps[5];
491 
492 
493  // These are all marked mutable because they
494  // are initialized lazily in a const accessor.
495  // I have yet to decide if this is the "correct"
496  // way to go about it.
497  mutable CreateSensors::PlayButton *m_playButton;
498  mutable CreateSensors::AdvanceButton *m_advanceButton;
499 
500  mutable CreateSensors::Wall *m_wall;
501  mutable CreateSensors::CliffLeft *m_cliffLeft;
502  mutable CreateSensors::CliffFrontLeft *m_cliffFrontLeft;
503  mutable CreateSensors::CliffFrontRight *m_cliffFrontRight;
504  mutable CreateSensors::CliffRight *m_cliffRight;
505  mutable CreateSensors::VirtualWall *m_virtualWall;
506 
507  mutable CreateSensors::WallSignal *m_wallSignal;
508  mutable CreateSensors::CliffLeftSignal *m_cliffLeftSignal;
509  mutable CreateSensors::CliffFrontLeftSignal *m_cliffFrontLeftSignal;
510  mutable CreateSensors::CliffFrontRightSignal *m_cliffFrontRightSignal;
511  mutable CreateSensors::CliffRightSignal *m_cliffRightSignal;
512  mutable CreateSensors::CargoBayAnalogSignal *m_cargoBayAnalogSignal;
513  mutable CreateSensors::CargoBayDigitalInputs *m_cargoBayDigitalInputs;
514 
515  mutable CreateSensors::IR *m_ir;
516 
517  mutable CreateSensors::ChargingState *m_chargingState;
518  mutable CreateSensors::BatteryTemperature *m_batteryTemperature;
519  mutable CreateSensors::BatteryCharge *m_batteryCharge;
520  mutable CreateSensors::BatteryCapacity *m_batteryCapacity;
521 
522  mutable CreateSensors::Angle *m_angle;
523  mutable CreateSensors::Distance *m_distance;
524 
525  mutable CreateSensors::BumpLeft *m_bumpLeft;
526  mutable CreateSensors::BumpRight *m_bumpRight;
527 
528  mutable CreateSensors::WheelDropLeft *m_wheelDropLeft;
529  mutable CreateSensors::WheelDropRight *m_wheelDropRight;
530  mutable CreateSensors::WheelDropCaster *m_wheelDropCaster;
531 
532  size_t m_i;
533  CreateScript m_script;
534  int m_tty;
535 #ifndef WIN32
536  pthread_mutex_t m_mutex;
537 #endif
538 };
539 
540 #endif